package cn.edu.nwpu.warehousemanagement.dao;

import cn.edu.nwpu.warehousemanagement.constantEnum.ReplenishStrategy;
import cn.edu.nwpu.warehousemanagement.pojo.InventoryConfig;
import cn.edu.nwpu.warehousemanagement.pojo.Product;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Repository
public interface InventoryConfigRepository extends JpaRepository<InventoryConfig, Long> {

    // ==================== 基础CRUD ====================
    // 继承自JpaRepository:
    // save()               - 创建/更新配置
    // findById()           - 根据ID查询(默认排除已删除)
    // deleteById()         - 根据ID软删除
    // findAll()            - 查询所有未删除配置

    //精确匹配ID
    Optional<InventoryConfig> findByIdAndDeletedFalse(Long id);

    // 查询包括已删除的记录
    @Query("SELECT ic FROM InventoryConfig ic WHERE ic.id = :id")
    Optional<InventoryConfig> findByIdIncludeDeleted(@Param("id") Long id);

    // 查询所有记录（包括已删除的）
    @Query("SELECT ic FROM InventoryConfig ic")
    List<InventoryConfig> findAllIncludeDeleted();

    // 物理删除
    @Modifying
    @Transactional
    @Query("DELETE FROM InventoryConfig ic WHERE ic.id = :id")
    void hardDeleteById(@Param("id") Long id);

    // ==================== 按商品查询 ====================
    // 精确查询商品配置（使用Product实体，排除已删除）
    Optional<InventoryConfig> findByProductAndDeletedFalse(Product product);

    // 精确查询商品配置（使用商品ID，排除已删除）
    Optional<InventoryConfig> findByProductIdAndDeletedFalse(Long productId);

    // 查询多个商品的配置（排除已删除）
    List<InventoryConfig> findByProductIdInAndDeletedFalse(List<Long> productIds);

    // ==================== 按库存策略查询 ====================
    // 查询使用指定补货策略的配置（排除已删除）
    List<InventoryConfig> findByReplenishStrategyAndDeletedFalse(ReplenishStrategy strategy);

    // 查询自动补货策略的配置（排除已删除）
    @Query("SELECT ic FROM InventoryConfig ic WHERE ic.replenishStrategy = 'AUTO' AND ic.deleted = false")
    List<InventoryConfig> findAutoReplenishConfigs();

    // ==================== 库存阈值查询 ====================
    // 查询需要预警的低库存配置（当前库存低于安全库存，排除已删除）
    @Query("SELECT ic FROM InventoryConfig ic JOIN Product p ON ic.product.id = p.id " +
            "WHERE p.quantity < ic.safetyStock AND ic.deleted = false")
    List<InventoryConfig> findLowStockConfigs();

    // 查询需要补货的配置（当前库存低于最小库存，排除已删除）
    @Query("SELECT ic FROM InventoryConfig ic JOIN Product p ON ic.product.id = p.id " +
            "WHERE p.quantity < ic.minStock AND ic.deleted = false")
    List<InventoryConfig> findNeedReplenishConfigs();

    // 查询库存超量的配置（当前库存超过最大库存，排除已删除）
    @Query("SELECT ic FROM InventoryConfig ic JOIN Product p ON ic.product.id = p.id " +
            "WHERE p.quantity > ic.maxStock AND ic.deleted = false")
    List<InventoryConfig> findOverstockConfigs();

    // ==================== 预警时间查询 ====================
    // 查询需要更新预警时间的配置（未预警或超过预警间隔，排除已删除）
    @Query("SELECT ic FROM InventoryConfig ic WHERE " +
            "(ic.lastAlertTime IS NULL OR ic.lastAlertTime < :thresholdTime) " +
            "AND ic.deleted = false")
    List<InventoryConfig> findConfigsNeedAlertUpdate(
            @Param("thresholdTime") LocalDateTime thresholdTime);

    // ==================== 自定义更新操作 ====================
    // 更新库存阈值（只更新未删除的）
    @Modifying
    @Transactional
    @Query("UPDATE InventoryConfig ic SET " +
            "ic.minStock = :minStock, " +
            "ic.maxStock = :maxStock, " +
            "ic.safetyStock = :safetyStock " +
            "WHERE ic.id = :id AND ic.deleted = false")
    int updateStockThresholds(
            @Param("id") Long id,
            @Param("minStock") Integer minStock,
            @Param("maxStock") Integer maxStock,
            @Param("safetyStock") Integer safetyStock);

    // 更新补货策略（只更新未删除的）
    @Modifying
    @Transactional
    @Query("UPDATE InventoryConfig ic SET ic.replenishStrategy = :strategy WHERE ic.id = :id AND ic.deleted = false")
    int updateReplenishStrategy(
            @Param("id") Long id,
            @Param("strategy") ReplenishStrategy strategy);

    // 批量更新预警时间（只更新未删除的）
    @Modifying
    @Transactional
    @Query("UPDATE InventoryConfig ic SET ic.lastAlertTime = :alertTime WHERE ic.id IN :ids AND ic.deleted = false")
    int batchUpdateAlertTime(
            @Param("ids") List<Long> ids,
            @Param("alertTime") LocalDateTime alertTime);

    // 软删除配置
    @Modifying
    @Transactional
    @Query("UPDATE InventoryConfig ic SET ic.deleted = true WHERE ic.id = :id")
    int softDeleteById(@Param("id") Long id);

    // 批量软删除
    @Modifying
    @Transactional
    @Query("UPDATE InventoryConfig ic SET ic.deleted = true WHERE ic.id IN :ids")
    int batchSoftDelete(@Param("ids") List<Long> ids);

    // 恢复软删除的配置
    @Modifying
    @Transactional
    @Query("UPDATE InventoryConfig ic SET ic.deleted = false WHERE ic.id = :id")
    int restoreById(@Param("id") Long id);

    // ==================== 统计查询 ====================
    // 统计使用各策略的配置数量（排除已删除）
    @Query("SELECT ic.replenishStrategy, COUNT(ic) FROM InventoryConfig ic WHERE ic.deleted = false GROUP BY ic.replenishStrategy")
    List<Object[]> countByReplenishStrategy();

    // 检查商品是否已存在未删除配置
    boolean existsByProductIdAndDeletedFalse(Long productId);

    // 检查商品是否已存在配置（包括已删除）
    @Query("SELECT COUNT(ic) > 0 FROM InventoryConfig ic WHERE ic.product.id = :productId")
    boolean existsByProductIdIncludeDeleted(@Param("productId") Long productId);


    // 分页查询所有未删除的库存配置
    Page<InventoryConfig> findByDeletedFalse(Pageable pageable);

    // 查询所有未删除的库存配置(不分页)
    List<InventoryConfig> findByDeletedFalse();
}